using dnAnalytics.LinearAlgebra;
using dnAnalytics.LinearAlgebra.IO;
using NUnit.Framework;

namespace dnAnalytics.Tests.LinearAlgebra.IO
{
    [TestFixture]
    public class MatlabMatrixReaderTest
    {
        [Test]
        public void ReadMatricesDenseSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix[] matrices = dmr.ReadMatrices(StorageType.Dense);
            Assert.AreEqual(30, matrices.Length);
            foreach (Matrix matrix in matrices)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }
        }

        [Test]
        public void ReadMatricesNoStorageSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix[] matrices = dmr.ReadMatrices();
            Assert.AreEqual(30, matrices.Length);
            foreach (Matrix matrix in matrices)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }
        }

        [Test]
        public void ReadFirstMatrixDenseSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/A.mat");
            Matrix matrix = dmr.ReadMatrix(StorageType.Dense);
            Assert.AreEqual(100, matrix.Rows);
            Assert.AreEqual(100, matrix.Columns);
            TestHelper.TestSignificantDigits(100.108979553704, matrix.FrobeniusNorm(), 13);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
        }

        [Test]
        public void ReadFirstMatrixNoStorageSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/A.mat");
            Matrix matrix = dmr.ReadMatrix();
            Assert.AreEqual(100, matrix.Rows);
            Assert.AreEqual(100, matrix.Columns);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            TestHelper.TestSignificantDigits(100.108979553704, matrix.FrobeniusNorm(), 13);
        }

        [Test]
        public void ReadNamedMatricesDenseSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix[] matrices = dmr.ReadMatrices(new[] { "Ad", "Au64" }, StorageType.Dense);
            Assert.AreEqual(2, matrices.Length);
            foreach (Matrix matrix in matrices)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }
        }

        [Test]
        public void ReadNamedMatricesNoStorageSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix[] matrices = dmr.ReadMatrices(new[] { "Ad" });
            Assert.AreEqual(1, matrices.Length);
            Assert.AreEqual(100, matrices[0].Rows);
            Assert.AreEqual(100, matrices[0].Columns);
            TestHelper.TestSignificantDigits(100.431635988639, matrices[0].FrobeniusNorm(), 13);
            Assert.AreEqual(typeof(DenseMatrix), matrices[0].GetType());
        }

          [Test]
        public void ReadNamedMatrixSparse()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/sparse-small.mat");
            Matrix matrix = dmr.ReadMatrix("S");
            Assert.AreEqual(100, matrix.Rows);
            Assert.AreEqual(100, matrix.Columns);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            TestHelper.TestSignificantDigits(17.6385090630805, matrix.FrobeniusNorm(), 12);
        }


        [Test]
        public void ReadNamedMatrixDenseSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix matrix = dmr.ReadMatrix("Ad", StorageType.Dense );
            Assert.AreEqual(100, matrix.Rows);
            Assert.AreEqual(100, matrix.Columns);
            TestHelper.TestSignificantDigits(100.431635988639, matrix.FrobeniusNorm(), 13);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
        }

        [Test]
        public void ReadNamedMatrixNoStorageSpecified()
        {
            MatlabMatrixReader dmr = new MatlabMatrixReader("./TestData/Matlab/collection.mat");
            Matrix matrix = dmr.ReadMatrix("Ad");
            Assert.AreEqual(100, matrix.Rows);
            Assert.AreEqual(100, matrix.Columns);
            TestHelper.TestSignificantDigits(100.431635988639, matrix.FrobeniusNorm(), 13);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
        }
    }
}